package Creational.Singleton;

import org.testng.annotations.Test;

import java.io.*;

public class LazyDemo {

	@Test(description = "多线程测试")
	public void t1() throws InterruptedException {
		for (int i = 0; i < 10; i++) {
			new Thread(() -> System.out.println(Lazy.getInstance().hashCode())).start();
		}
	}

	@Test(description = "序列化测试 这里没生效")
	public void t2() throws Exception {
		Lazy instance = Lazy.getInstance();
		ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("target/test"));
		outputStream.writeObject(instance);
		outputStream.close();

		ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("target/test"));
		Lazy readLazy = ((Lazy) inputStream.readObject());
		System.out.println(readLazy == instance);
	}
}

class Lazy implements Serializable {

	static final long serialVersionUID = 42L;

	private static volatile Lazy instance;

	private Lazy() {}

	Lazy readResolve() throws ObjectStreamException {
		return instance;
	}

	public static Lazy getInstance() {
		if (instance == null) {
			synchronized (Lazy.class) {
				if (instance == null) {
					instance = new Lazy();
					// 字节码层
					// 1.分配空间
					// 2.初始化
					// 3.引用赋值

					// 所以如果再多线程环境 2 3 颠倒了那么对象在没有初始化的情况下因为已经赋值了 其他线程在就有可能拿到了空对象 导致空指针
				}
			}
		}
		return instance;
	}

}
